package com.telit.dispose.service.dispose.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.telit.common.entity.PageData;
import com.telit.common.exception.ForestBaseException;
import com.telit.common.util.ExcelUtil;
import com.telit.common.util.JwtTokenUtils;
import com.telit.dispose.dao.dispose.PlatMetaFieldMapper;
import com.telit.dispose.dao.dispose.PlatMetaTableMapper;
import com.telit.dispose.dao.resourceManagement.FireResourceCategoryDao;
import com.telit.dispose.dto.*;
import com.telit.dispose.entity.FireResourceCategory;
import com.telit.dispose.entity.dispose.PlatMetaFieldEntity;
import com.telit.dispose.entity.dispose.PlatMetaTableEntity;
import com.telit.dispose.feign.UpmsFeignClient;
import com.telit.dispose.service.dispose.PlatMetaTableService;
import com.telit.dispose.service.resourceManagement.FireResourceService;
import com.telit.dispose.utils.ConvertPinYinUtil;
import com.telit.dispose.vo.dispose.PlatMetaTableVO;
import com.telit.dispose.vo.dispose.PlatTableAndFileVO;
import com.telit.dispose.vo.dispose.PlatTableVO;
import com.telit.dispose.vo.resourceManagement.ResourceSimpVO;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 元数据-表业务逻辑实现
 * Create by Chencf 2022/08/05
 */

@Service
public class PlatMetaTableServiceImpl implements PlatMetaTableService {

    @Autowired
    private PlatMetaTableMapper platMetaTableMapper;

    @Autowired
    private PlatMetaFieldMapper platMetaFieldMapper;

    @Autowired
    private FireResourceService fireResourceService;

    @Autowired
    private FireResourceCategoryDao fireResourceCategoryDao;

    @Autowired
    private UpmsFeignClient upmsFeignClient;

    //经度
    private static final String LNG_PATTERN = "^[\\-\\+]?(0(\\.\\d{1,8})?|([1-9](\\d)?)(\\.\\d{1,8})?|1[0-7]\\d{1}(\\.\\d{1,8})?|180(\\.0{1,8})?)$";
    //纬度
    private static final String LAT_PATTERN = "^[\\-\\+]?((0|([1-8]\\d?))(\\.\\d{1,8})?|90(\\.0{1,8})?)$";

    //创建表
    @Override
    @Transactional
    public boolean createTablePlatMetaTable(PlatMetaTableEntityDTO dto) {
        PlatMetaTableEntity entity = dto.getPlatMetaTableEntity();
        //直接创建表和创建字段接口
        QueryWrapper<PlatMetaTableEntity> wrapperCode = new QueryWrapper<>();
        //补全表的code  目前是根据前端的name进行转换
        entity.setCode(ConvertPinYinUtil.getPinyin(entity.getName()));
        //code
        wrapperCode.eq("code", entity.getCode());
        wrapperCode.eq("delete_flag", PlatMetaTableEntity.IS_CREATED_NO);
        int countCode = platMetaTableMapper.selectCount(wrapperCode);
        if (countCode > 0) {
            // throw new BaseException(CommonResultCode.CODE_EXIST, "code编码已经存在!!");
            throw new ForestBaseException("code编码已经存在!!");
        }

        QueryWrapper<PlatMetaTableEntity> wrapperName = new QueryWrapper<>();
        wrapperName.eq("name", entity.getName());
        wrapperName.eq("delete_flag", PlatMetaTableEntity.IS_CREATED_NO);
        int countName = platMetaTableMapper.selectCount(wrapperName);
        if (countName > 0) {
//            throw new BaseException(CommonResultCode.NAME_EXIST, "name已经存在!!");
            throw new ForestBaseException("name已经存在!!");
        }
        String realName = JwtTokenUtils.getRealName();

        //创建表和表对应字段
        //创建表
        entity.setCreateDate(new Date());
        entity.setCreateName(realName);
        entity.setCategory(dto.getId().toString());
        platMetaTableMapper.insert(entity);
        //创建表对应字段  创建真实的表  表名称 prefix+code组成
        platMetaTableMapper.createTable(entity);
        for (PlatMetaFieldEntity platMetaFieldEntity : entity.getFields()) {
            platMetaFieldEntity.setIsCreate(PlatMetaTableEntity.IS_CREATED_YES);
            platMetaFieldEntity.setTableId(entity.getId());
            platMetaFieldEntity.setCreateName(realName);
            platMetaFieldEntity.setUpdateName(realName);
            platMetaFieldEntity.setCreateDate(new Date());
            platMetaFieldMapper.insert(platMetaFieldEntity);
        }
        //2022-9-23提供方法同步添加数据到资源分类表里面
        FireResourceCategory fireResourceCategory = getFireResourceCategory(entity, dto);
        fireResourceService.addResource(fireResourceCategory);

        return true;
    }


    //查询所有的表已经对应字段
    @Override
    public Object selectAllTableAndFiles(TableFindDTO tableFindDTO) {
//        if (StringUtils.isNoneBlank(tableFindDTO.getName())) {
//            tableFindDTO.setName("%" + tableFindDTO.getName() + "%");
//        }

        IPage<PlatMetaTableVO> platMetaTableEntityIPage = new Page<>(tableFindDTO.getPage(), tableFindDTO.getRows());
        IPage<PlatMetaTableVO> pageList = platMetaTableMapper.selectAllTablePage(platMetaTableEntityIPage,
                tableFindDTO);
        List<PlatMetaTableVO> allTable = pageList.getRecords();
        for (PlatMetaTableVO table : allTable) {
            List<PlatMetaFieldEntity> fields = getPlatMetaFieldList(table.getId());
            table.setFields(fields);
        }

        pageList.setRecords(allTable);
        PageData<Object> pageData = new PageData<>();
        pageData.setDatas(pageList.getRecords());
        pageData.setCount((int) pageList.getTotal());
        pageData.setCurrent((int) pageList.getCurrent());
        pageData.setSize((int) pageList.getSize());
        return pageData;

    }

    //查询所有的表已经对应的表名称
    @Override
    public List<PlatMetaFieldEntity> selectTableAndFilesByTableId(String tableId) {
        List<PlatMetaFieldEntity> platMetaTableById = getPlatMetaTableById(tableId);
        return platMetaTableById;
    }


    @Override
    public PlatMetaTableEntityDTO selectTableByTableId(String tableId) {
        //查询表
        // PlatMetaTableEntityDTO platMetaTableEntityDTO = new PlatMetaTableEntityDTO();
        //
        PlatMetaTableEntityDTO tableEntity = platMetaTableMapper.selectTableByTableId(tableId);
        //查询表数据
        PlatMetaTableEntity table = platMetaTableMapper.selectById(tableId);
        //查询表字段
        List<PlatMetaFieldEntity> files = getPlatMetaTableById(tableId);
        //去除固定字段
        List<PlatMetaFieldEntity> collect = files.stream().filter(platMetaFieldEntity ->
                !platMetaFieldEntity.getCode().equals("xzqh") &&
                        !platMetaFieldEntity.getCode().equals("xzqhcode") &&
                        !platMetaFieldEntity.getCode().equals("longitude") &&
                        !platMetaFieldEntity.getCode().equals("latitude") &&
                        !platMetaFieldEntity.getCode().equals("name")).collect(Collectors.toList());
        table.setFields(collect);
        tableEntity.setPlatMetaTableEntity(table);
        return tableEntity;
    }

    @Override
    @Transactional
    public void deleteTable(String tableId) {
        String realName = JwtTokenUtils.getRealName();
        //将配置下线
        PlatMetaTableEntity tableEntity = new PlatMetaTableEntity();
        tableEntity.setId(tableId);
        tableEntity.setDeleteFlag(PlatMetaTableEntity.IS_CREATED_YES);
        tableEntity.setUpdateDate(new Date());
        tableEntity.setUpdateName(realName);
        platMetaTableMapper.updateById(tableEntity);
        //将所有的字段下线
        platMetaFieldMapper.updateByTableIdAndId(realName, new Date(), null, null, tableId);
        String tableName = getTableName(tableId);
        platMetaTableMapper.dropTable(tableName);

        //将fire_resource_category相关数据修改
        String name = getTableCode(tableId);
        fireResourceCategoryDao.updateDelete(name);

    }


    @Override
    @Transactional
    public boolean updateOrDeleteTableFile(Integer flag, PlatMetaTableEntity entity) {
        String realName = JwtTokenUtils.getRealName();
        //判断
        if (flag == 1) {
            //删除字段的逻辑需要前后端配合，注意此处逻辑在调整前面务必联系对应前端问清楚逻辑
            for (PlatMetaFieldEntity fieldEntity : entity.getFields()) {
                platMetaFieldMapper.updateByTableIdAndId(realName, new Date(), fieldEntity.getCode() + "bank",
                        fieldEntity.getId(), entity.getId());
                //将原表的字段也修改
                PlatMetaTableEntity tableEntity = platMetaTableMapper.selectById(entity.getId());
                String tableName = tableEntity.getPrefix() + tableEntity.getCode();
                platMetaFieldMapper.updateColumn(tableName, fieldEntity.getCode(), fieldEntity.getCode() + "bank");
            }
        }
        //新增字段
        if (flag == 0) {
            //判断字段名称是否存在
            for (PlatMetaFieldEntity fieldEntity : entity.getFields()) {
                QueryWrapper<PlatMetaFieldEntity> wrapperCode = new QueryWrapper<>();
                //code  同一个表下code不能重复
                wrapperCode.eq("code", fieldEntity.getCode());
                wrapperCode.eq("table_id", entity.getId());
                wrapperCode.eq("delete_flag", "0");
                int countCode = platMetaFieldMapper.selectCount(wrapperCode);
//
//                QueryWrapper<PlatMetaFieldEntity> wrapperName = new QueryWrapper<>();
//                //name  同一个表下name不能重复
//                wrapperName.eq("name", entity.getCode());
//                wrapperName.eq("table_id", entity.getId());
//                wrapperName.eq("delete_flag","0");
//                int countName = platMetaFieldMapper.selectCount(wrapperCode);
                //由于前端会将所有的字段传过来，所以此处逻辑后端来处理 将存在的字段排除
                if (countCode == 0) {
                    fieldEntity.setCreateName(realName);
                    fieldEntity.setCreateDate(new Date());
                    fieldEntity.setDeleteFlag("0");
                    fieldEntity.setTableId(entity.getId());
                    platMetaFieldMapper.insert(fieldEntity);

                    //将字段添加多对应的表里面 alter语句
                    //根据tableid查询对应的tablename
                    PlatMetaTableEntity tableEntity = platMetaTableMapper.selectById(entity.getId());
                    //给表添加字段要素 表名称+字段name+字段类型+字段长度
                    platMetaTableMapper.updateTable(
                            tableEntity.setTableName(tableEntity.getCode(), tableEntity.getPrefix()),
                            fieldEntity.getCode(), fieldEntity.getType(), fieldEntity.getLength());

                }
            }
        }
        return true;
    }

    @Override
    public boolean updateIconShow(PlatMetaTableUpdateDTO dto) {
        platMetaTableMapper.updateIconShow(dto.getIconShow(), dto.getTableId());
        return true;
    }

    /**
     * 获取字段集
     *
     * @param tableId 表ID
     *
     * @return List<PlatMetaFieldEntity>
     */
    private List<PlatMetaFieldEntity> getPlatMetaFieldList(String tableId) {
        QueryWrapper<PlatMetaFieldEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("table_id", tableId);
        queryWrapper.eq("delete_flag", "0");
        queryWrapper.orderByAsc("sort");
        return platMetaFieldMapper.selectList(queryWrapper);
    }

    public PlatMetaTableEntity getPlatMetaTableByName(String tableName) {
        PlatMetaTableEntity entity = null;
        if (StringUtils.isNotBlank(tableName)) {
            entity = platMetaTableMapper.selectByName(tableName);
            if (entity != null) {
                List<PlatMetaFieldEntity> fields = getPlatMetaFieldList(entity.getId());
                entity.setFields(fields);
            }
        }
        return entity;
    }


    public List<PlatMetaFieldEntity> getPlatMetaTableById(String tableId) {
        List<PlatMetaFieldEntity> fields = getPlatMetaFieldList(tableId);
        return fields;
    }


    //查询所有的配置信息  对应会给表的信息
    @Override
    public List<PlatMetaTableEntity> findTypeList() {
        List<PlatMetaTableEntity> typeList = platMetaTableMapper.findTypeList();
        typeList.forEach(platMetaTableEntity ->
                platMetaTableEntity.setTableName(platMetaTableEntity.getCode(), platMetaTableEntity.getPrefix())
        );
        return typeList;
    }


    @Override
    public PlatTableAndFileVO findInfo(String json) {
        PlatTableAndFileVO vo = new PlatTableAndFileVO();
        PlatMetaTableEntity entity = platMetaTableMapper.selectById(json);
        vo.setType(entity);
        List<PlatMetaFieldEntity> files = platMetaFieldMapper.selectAllFilesByTableId(json);
        entity.setFields(files);
        vo.setTable(entity);
        return vo;
    }


    @Override
    public Object pageList(String tableId, Integer current, Integer size, String name, String xzqhcode) {
        //step1 先拿到对应的表有哪些字段  plat_meta_field表里面code为字段名称   目前在前端进行处理
        List<PlatMetaFieldEntity> files = platMetaFieldMapper.selectAllFilesByTableId(tableId);
        List<String> codeList = files.stream().map(PlatMetaFieldEntity::getCode).collect(Collectors.toList());
        //查询表的名称
        String tableName = getTableName(tableId);
        if (StringUtils.isNotBlank(xzqhcode)) {
            xzqhcode = xzqhcode + "%";
        }
        if (StringUtils.isNotBlank(name)) {
            name = "%" + name + "%";
        }
        //查询所有的
        IPage page = new Page<>(current, size);
        int count = platMetaFieldMapper.selectCountByTableName(tableName, name, xzqhcode);
        //将plat_meta_field表里面的code作为查询的的字段
//        List<Map> datas = platMetaFieldMapper.selectPageList(size, ((current - 1) * size), tableName, name, xzqhcode);
        IPage<Map> datas = platMetaFieldMapper.selectPageList1(page, tableName, name, xzqhcode);
        //这里暂时进行后端分页，因为考虑是纯表单的问题，数据量可能不会上升到一个量，目前考虑做sql分页
//        Map<Object, Object> dataMap = new HashMap<>();
//        dataMap.put("datas", datas);
//        dataMap.put("count", count);
//        dataMap.put("current", current);
//        dataMap.put("size", size);


        PageData<Object> pageData = new PageData<>();
        pageData.setDatas(datas.getRecords());
        pageData.setCount((int) datas.getTotal());
        pageData.setCurrent((int) datas.getCurrent());
        pageData.setSize((int) datas.getSize());

        return pageData;
    }

    //根据表名称获取要insert到那张表里面
    @Override
    @Transactional
    public Integer save(String tableId, String data) {
        List<PlatMetaFieldEntity> files = platMetaFieldMapper.selectAllFilesByTableId(tableId);
        //需要添加的数据字段名称
        List<String> codeList = files.stream().map(PlatMetaFieldEntity::getCode).collect(Collectors.toList());
        String tableName = getTableName(tableId);

        return updateTableData(data, codeList, tableName, null, null);

    }


    //编辑
    @Override
    @Transactional
    public Integer edit(String tableId, String detailId, String data) {
        //查询对应表对应id的数据
        List<PlatMetaFieldEntity> files = platMetaFieldMapper.selectAllFilesByTableId(tableId);
        //需要添加的数据字段名称
        List<String> codeList = files.stream().map(PlatMetaFieldEntity::getCode).collect(Collectors.toList());
        String tableName = getTableName(tableId);
        Map oldDataMap = platMetaFieldMapper.findDetailByTableNameAndDetailId(tableName, detailId);
        String create_name = null;
        String create_date = null;
        if (Objects.nonNull(oldDataMap.get("create_name"))) {
            create_name = oldDataMap.get("create_name").toString();
        }
        if (Objects.nonNull(oldDataMap.get("create_date"))) {
            create_date = oldDataMap.get("create_date").toString();
        }
        //将原数据deleteflag置为1  删除状态
        platMetaFieldMapper.updateDeleteFlagByTableName(tableName, JwtTokenUtils.getRealName(), new Date(), detailId);
        return updateTableData(data, codeList, tableName, create_name, create_date);

    }

    @Override
    public Map detail(String tableId, String deatilId) {
        //根据tableId查询对应表名称
        String tableName = getTableName(tableId);
        //根据表名称和对应详情id查询对应数据
        Map detailByTableNameAndDetailId = platMetaFieldMapper.findDetailByTableNameAndDetailId(tableName, deatilId);
        return detailByTableNameAndDetailId;
    }

    @Override
    @Transactional
    public Integer delete(String tableId, String detailId) {
        //查询对应表对应id的数据
        List<PlatMetaFieldEntity> files = platMetaFieldMapper.selectAllFilesByTableId(tableId);
        //需要添加的数据字段名称
        List<String> codeList = files.stream().map(PlatMetaFieldEntity::getCode).collect(Collectors.toList());
        String tableName = getTableName(tableId);
        Map oldDataMap = platMetaFieldMapper.findDetailByTableNameAndDetailId(tableName, detailId);
//        String create_name = oldDataMap.get("create_name").toString();
//        String create_date = oldDataMap.get("create_date").toString();
        //将原数据deleteflag置为1  删除状态
        platMetaFieldMapper.updateDeleteFlagByTableName(tableName, JwtTokenUtils.getRealName(), new Date(), detailId);
        // platMetaTableMapper.dropTable(tableName);
        return 1;
    }


    @Override
    public List<PlatTableVO> selectAllTable(String flag) {
        List<PlatTableVO> result = new ArrayList<>();
        List<PlatMetaTableEntity> platMetaTableEntities = platMetaTableMapper.selectAllTable(flag);
        platMetaTableEntities.forEach(platMetaTableEntity -> {
            PlatTableVO platTableVO = new PlatTableVO();
            platTableVO.setName(platMetaTableEntity.getName());
            platTableVO.setId(platMetaTableEntity.getId());
            platTableVO.setPrefix(platMetaTableEntity.getPrefix());
            platTableVO.setCode(platMetaTableEntity.getCode());
            platTableVO.setCategory(platMetaTableEntity.getCategory());
            platTableVO.setTableName(platMetaTableEntity.getPrefix() + platMetaTableEntity.getCode());
            //补全img数据
            platTableVO.setImg(fireResourceCategoryDao.selectImgByName(platMetaTableEntity.getName()));
            platTableVO.setIconImg(fireResourceCategoryDao.selectIconImgByName(platMetaTableEntity.getName()));
            result.add(platTableVO);
        });
        return result;
    }


    @Override
    public List<Map> selectTableInfoByTableName(String tables, String districtCode) throws Exception {
        if (StringUtils.isNotBlank(districtCode)) {
            districtCode = districtCode + "%";
        }
        List<Map> result = new ArrayList<>();
        //根据表名称查询表信息
        //转list
        List<String> tableNameList = com.telit.common.util.StringUtils.convertStringList(tables);
        for (String tableName : tableNameList) {
            List<Map> tableMap = new ArrayList<>();
            Map<String, List<Map>> tableInfoMap = new HashMap<>();
            //判断是否存在视频和无人机
            //根据资源表名称查询对应资源数量
            if (tableName.contains("uav")) {
                List<ResourceSimpVO> allUav = platMetaFieldMapper.findAllUav(districtCode);
                for (ResourceSimpVO resourceSimpVO : allUav) {
                    Map map = new HashMap<>();
                    map.put("id", resourceSimpVO.getId());
                    map.put("isOnline", resourceSimpVO.getIsOnline());
                    map.put("latitude", resourceSimpVO.getLatitude());
                    map.put("longitude", resourceSimpVO.getLongitude());
                    map.put("resourceName", resourceSimpVO.getResourceName());
                    map.put("name", resourceSimpVO.getResourceName());
                    map.put("flag", 1);
                    tableMap.add(map);
                }
            } else if (tableName.contains("camera")) {
                List<ResourceSimpVO> allCamera = platMetaFieldMapper.findAllCamera(districtCode);
                for (ResourceSimpVO resourceSimpVO : allCamera) {
                    Map map = new HashMap<>();
                    map.put("id", resourceSimpVO.getId());
                    map.put("isOnline", resourceSimpVO.getIsOnline());
                    map.put("latitude", resourceSimpVO.getLatitude());
                    map.put("longitude", resourceSimpVO.getLongitude());
                    map.put("resourceName", resourceSimpVO.getResourceName());
                    map.put("name", resourceSimpVO.getResourceName());
                    map.put("flag", 1);
                    tableMap.add(map);
                }
            } else {
                tableMap = platMetaFieldMapper.findDetailByTableName(tableName, districtCode);
                for (Map map : tableMap) {
                    map.put("flag", 0);
                }
            }
            //拿到表数据返回
            tableInfoMap.put(tableName, tableMap);
            result.add(tableInfoMap);

        }
        return result;
    }


    @Override
    public List<Map> selectTableInfoByTableName1(String longitude, String latitude,String tables, String districtCode,Integer page,Integer rows,String radius) throws Exception {
        if (StringUtils.isNotBlank(districtCode)) {
            districtCode = districtCode + "%";
        }
        List<Map> result = new ArrayList<>();
        //根据表名称查询表信息
        //转list
        List<String> tableNameList = com.telit.common.util.StringUtils.convertStringList(tables);
        for (String tableName : tableNameList) {
            List<Map> tableMap = new ArrayList<>();
            Map<String, List<Map>> tableInfoMap = new HashMap<>();
            //判断是否存在视频和无人机
            //根据资源表名称查询对应资源数量
            if (tableName.contains("uav")) {
                IPage page1 = new Page<>(page, rows);
                List<ResourceSimpVO> allUav = platMetaFieldMapper.findAllUav1(page1,longitude,latitude,districtCode,radius);
                for (ResourceSimpVO resourceSimpVO : allUav) {
                    Map map = new HashMap<>();
                    map.put("id", resourceSimpVO.getId());
                    map.put("isOnline", resourceSimpVO.getIsOnline());
                    map.put("latitude", resourceSimpVO.getLatitude());
                    map.put("longitude", resourceSimpVO.getLongitude());
                    map.put("resourceName", resourceSimpVO.getResourceName());
                    map.put("name", resourceSimpVO.getResourceName());
                    map.put("flag", 1);
                    tableMap.add(map);
                }
            } else if (tableName.contains("camera")) {
                IPage page1 = new Page<>(page, rows);
                List<ResourceSimpVO> allCamera = platMetaFieldMapper.findAllCamera1(page1,longitude,latitude,districtCode,radius);
                for (ResourceSimpVO resourceSimpVO : allCamera) {
                    Map map = new HashMap<>();
                    map.put("id", resourceSimpVO.getId());
                    map.put("isOnline", resourceSimpVO.getIsOnline());
                    map.put("latitude", resourceSimpVO.getLatitude());
                    map.put("longitude", resourceSimpVO.getLongitude());
                    map.put("resourceName", resourceSimpVO.getResourceName());
                    map.put("name", resourceSimpVO.getResourceName());
                    map.put("flag", 1);
                    tableMap.add(map);
                }
            } else {
                IPage page1 = new Page<>(page, rows);
                tableMap = platMetaFieldMapper.findDetailByTableName1(page1,longitude,latitude,tableName, districtCode,radius);
                for (Map map : tableMap) {
                    map.put("flag", 0);
                }
            }
            //拿到表数据返回
            tableInfoMap.put(tableName, tableMap);
            result.add(tableInfoMap);

        }
        return result;
    }

    private String getTableName(String tableId) {
        PlatMetaTableEntity entity = platMetaTableMapper.selectById(tableId);
        return entity.getPrefix() + entity.getCode();
    }

    private String getTableCode(String tableId) {
        PlatMetaTableEntity entity = platMetaTableMapper.selectById(tableId);
        return entity.getName();
    }

    private int insertTableData(String data, List<String> codeList, String tableName) {
        //将String 类型data转成json
        JSONObject jsonData = JSONObject.parseObject(data);
        LinkedList<Object> valueList = new LinkedList<>();
        for (String code : codeList) {
            String s = jsonData.get(code).toString();
            s = "'" + s + "'";
            valueList.add(s);
        }
        //补全固定字段值
        valueList.add("'0'");
        valueList.add("'0'");
        valueList.add("'" + JwtTokenUtils.getRealName() + "'");
        valueList.add("'" + DateUtil.now() + "'");
        valueList.add("'0'");
        valueList.add("'" + JwtTokenUtils.getRealName() + "'");
        //每一个表里面都会添加行政区划
        //valueList.add("'" + jsonData.get("xzqh") + "'");
        valueList.add("'" + DateUtil.now() + "'");
        valueList.add("'0'");
        //列表的名称
        String replace = codeList.toString().replace("[", "");
        String file = replace.replace("]", "");

        String values = valueList.toString().replace("[", "");
        String value = values.replace("]", "");
        String id = "'" + UUID.randomUUID().toString().substring(0, 10) + "'";
        platMetaFieldMapper.insertDataByTableName(id, file, tableName, value);
        return 1;
    }

    //data为前端传入的数据    codeList为表里面字段的集合
    private Integer updateTableData(String data, List<String> codeList, String tableName, String create_name,
                                    String create_date) {
        //重新添加数据
        //将String 类型data转成json
        JSONObject jsonData = JSONObject.parseObject(data);
        if (Objects.isNull(jsonData.get("longitude")) || Objects.isNull("latitude")) {
            throw new ForestBaseException("经纬度不能为空");
        }
//        if (!Pattern.matches(LNG_PATTERN, jsonData.get("longitude").toString()) && !Pattern.matches(LAT_PATTERN, jsonData.get("latitude").toString())) {
//            throw new ForestBaseException("经纬度格式错误");
//        }
        LinkedList<Object> valueList = new LinkedList<>();
        for (String code : codeList) {
            String s = "''";
            if (Objects.nonNull(jsonData.get(code))) {
                s = "'" + jsonData.get(code).toString() + "'";
                //s = "'" + s + "'";
            }
            valueList.add(s);
        }
        valueList.add("'0'");
        valueList.add("'0'");
        if (StringUtils.isNotBlank(create_date)) {
            valueList.add("'" + create_name + "'");
        } else {
            valueList.add("'" + JwtTokenUtils.getRealName() + "'");
        }
        if (StringUtils.isNotBlank(create_date)) {
            valueList.add("'" + create_date + "'");
        } else {
            valueList.add("'" + DateUtil.now() + "'");
        }
        valueList.add("'0'");
        valueList.add("'" + JwtTokenUtils.getRealName() + "'");
        //每一个表里面都会添加行政区划xzqh1字段
        //  valueList.add("0");
        valueList.add("'" + DateUtil.now() + "'");
        valueList.add("'0'");
        //列表的名称
        String replace = codeList.toString().replace("[", "");
        String file = replace.replace("]", "");
        String values = valueList.toString().replace("[", "");
        String value = values.replace("]", "");
        String id = "'" + UUID.randomUUID().toString().substring(0, 10) + "'";
        platMetaFieldMapper.insertDataByTableName(id, file, tableName, value);
        return 1;
    }


    @NotNull
    private FireResourceCategory getFireResourceCategory(PlatMetaTableEntity entity, PlatMetaTableEntityDTO dto) {
        FireResourceCategory fireResourceCategory = new FireResourceCategory();
        fireResourceCategory.setParentId(dto.getId());
        fireResourceCategory.setParentName(dto.getCategoryName());
        fireResourceCategory.setCatName(entity.getName());
        fireResourceCategory.setImg(dto.getImg());
        fireResourceCategory.setIconImg(dto.getIconImg());
        fireResourceCategory.setSortNum(dto.getSortNum());
        fireResourceCategory.setDeleted(false);
        return fireResourceCategory;
    }

    public static <T> List<Map<String, Object>> objectList2ListMap(List<T> objectList) throws Exception {
        ArrayList<Map<String, Object>> resultList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        for (T t : objectList) {
            resultList.add(object2Map(t));
        }
        return resultList;
    }


    public static Map<String, Object> object2Map(Object obj) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(obj));
        }
        return map;
    }


    //到出数据
    @Override
    public void commExportResource(String tableId, String tableName, String resourceName, HttpServletRequest request,
                                   HttpServletResponse response, String xzqhcode, String name) {
        //step 1 根据表名称查询表对应的列名称
        List<PlatMetaFieldEntity> tableFileList = platMetaFieldMapper.selectAllFilesByTableId(tableId);
        //根据表id查询表的名称
        Map<String, String> map = tableFileList.stream().collect(
                Collectors.toMap(PlatMetaFieldEntity::getCode, PlatMetaFieldEntity::getName, (key1, key2) -> key1));
        //{xzqh=行政区划, address=详细地址, rwlx=任务类型, txsb=通信设备, latitude=纬度, usestatus=使用状态, gsfs=供水方式, type=类型, szsd=设站时段, jczfzr=检查站负责人, zfmj=站房面积, jssj=建设时间, cnfs=采暖方式, name=名称, jscb=建设成本, gdfs=供电方式, hb=海拔, ssgldw=设备管理单位, moneyresource=建设时间, sssydw=设备使用单位, longitude=经度}
        //step 2 拿到所有的列字段名称
        Set<String> columnCodes = map.keySet();
        //[设备使用单位, 供电方式, 建设时间, 设站时段, 建设成本, 站房面积, 名称, 检查站负责人, 通信设备, 详细地址, 海拔, 设备管理单位, 行政区划, 纬度,    采暖方式, 经度,    任务类型, 供水方式, 使用状态, 类型]
//        [sssydw,     gdfs,     jssj, szsd,     jscb,    zfmj, name, jczfzr,     txsb,     address, hb, ssgldw,      xzqh,  latitude, cnfs, longitude, rwlx, gsfs, usestatus, type]
        // step 3 拿到所有的表字段code
        Collection<String> columnNames = map.values();
        String s = columnCodes.toString();
        String files = s.replace("[", "").replace("]", "");
        if (StringUtils.isNotBlank(xzqhcode)) {
            xzqhcode = xzqhcode + "%";
        }
        if (StringUtils.isNotBlank(name)) {
            name = "%" + name + "%";
        }
        //拿到所有的表code  查询对应数据表的数据
        List<Map> detailByTableName = platMetaFieldMapper.findDetailByTableNameAndFiles(files, tableName, xzqhcode,
                name);
        //拿到数据开始填充结果
        // 封装data数据
        List<Map<String, Object>> datas = new LinkedList<>();
        if (detailByTableName != null && !detailByTableName.isEmpty()) {
            for (int i = 0; i < detailByTableName.size(); i++) {
                Map dataMap = detailByTableName.get(i);
                if (dataMap != null) {
                    Map<String, Object> data = new HashMap<>();
                    for (String code : columnCodes) {
                        data.put("number", i + 1);
                        data.put(code, dataMap.get(code));
                    }
                    datas.add(data);
                }
            }
        }
        String title = resourceName;
        //将columnCodes转数组
        String[] arrkeys = columnCodes.toArray(new String[columnCodes.size()]);
        String[] names = columnNames.toArray(new String[columnNames.size()]);
        ExcelUtil.download(datas, arrkeys, names, title, title, request, response);

    }


    @Override
    public void commImportTemplate(String tableId, String tableName, String resourceName, HttpServletRequest request,
                                   HttpServletResponse response) {
        //step 1 根据表名称查询表对应的列名称
        List<PlatMetaFieldEntity> tableFileList = platMetaFieldMapper.selectAllFilesByTableId(tableId);
        //根据表id查询表的名称
        Map<String, String> map = tableFileList.stream().collect(
                Collectors.toMap(PlatMetaFieldEntity::getCode, PlatMetaFieldEntity::getName, (key1, key2) -> key1));
        //{xzqh=行政区划, address=详细地址, rwlx=任务类型, txsb=通信设备, latitude=纬度, usestatus=使用状态, gsfs=供水方式, type=类型, szsd=设站时段, jczfzr=检查站负责人, zfmj=站房面积, jssj=建设时间, cnfs=采暖方式, name=名称, jscb=建设成本, gdfs=供电方式, hb=海拔, ssgldw=设备管理单位, moneyresource=建设时间, sssydw=设备使用单位, longitude=经度}
        //step 2 拿到所有的列字段名称
        Set<String> columnCodes = map.keySet();
        //[设备使用单位, 供电方式, 建设时间, 设站时段, 建设成本, 站房面积, 名称, 检查站负责人, 通信设备, 详细地址, 海拔, 设备管理单位, 行政区划, 纬度,    采暖方式, 经度,    任务类型, 供水方式, 使用状态, 类型]
//        [sssydw,     gdfs,     jssj, szsd,     jscb,    zfmj, name, jczfzr,     txsb,     address, hb, ssgldw,      xzqh,  latitude, cnfs, longitude, rwlx, gsfs, usestatus, type]
        // step 3 拿到所有的表字段code

        Collection<String> columnNames = map.values();
        Collection<String> columnName = changecolumName(columnNames);
        List<Map<String, Object>> datas = new LinkedList<>();
        String title = resourceName;
        //将columnCodes转数组
        String[] arrkeys = columnCodes.toArray(new String[columnCodes.size()]);
        String[] names = columnName.toArray(new String[columnName.size()]);
        ExcelUtil.download(datas, arrkeys, names, title, title, request, response);
    }


    //数据导入
    @Override
    public void commLeadData(String tableId, String tableName, MultipartFile file) {
        String realName = JwtTokenUtils.getRealName();
        //step 1 根据表名称查询表对应的列名称
        List<PlatMetaFieldEntity> tableFileList = platMetaFieldMapper.selectAllFilesByTableId(tableId);

        //拿到所有的表的数据
        Map<String, String> map = tableFileList.stream().collect(
                Collectors.toMap(PlatMetaFieldEntity::getCode, PlatMetaFieldEntity::getName, (key1, key2) -> key1));
        //{xzqh=行政区划, address=详细地址, rwlx=任务类型, txsb=通信设备, latitude=纬度, usestatus=使用状态, gsfs=供水方式, type=类型, szsd=设站时段, jczfzr=检查站负责人, zfmj=站房面积, jssj=建设时间, cnfs=采暖方式, name=名称, jscb=建设成本, gdfs=供电方式, hb=海拔, ssgldw=设备管理单位, moneyresource=建设时间, sssydw=设备使用单位, longitude=经度}
        //step 2 拿到所有的列code
        Set<String> columnCodes = map.keySet();
        //字段名称
        for (String s : columnCodes) {
            s = "'" + s + "'";
        }

        String columsCode = columnCodes.toString().replace("[", "");
        String colums = columsCode.replace("]", "");


        //读取表格数据
        //解析整个Excel
        List<List<String>> data = null;
        try (InputStream is = file.getInputStream()) {
            data = ExcelUtil.getListByExcel(is, file.getOriginalFilename());
        } catch (Exception e) {
            throw new ForestBaseException("文件流读取失败");
        }
        if (data.size() < 2) {
            throw new ForestBaseException("您导入的Excel文件内容为空");
        }
        //校验第二行
        List<String> second = data.get(1);
        if (StringUtils.isBlank(second.get(0))) {
            throw new ForestBaseException("您导入的Excel非标准模板，请下载标准模板导入");

        }
        //拿到第一行数据   判断模板是否被改动（主要是添加字段或者减少字段）
        List<String> first = data.get(0);
        //校验excel是否含有固有的字段
        checkColums(first);

        Collection<String> columnName = map.values();

        //添加必填字段
        List<String> changecolumName = changecolumName(columnName);
        int mcIndex = changecolumName.indexOf("名称(必填)");
        int xzqhIndex = changecolumName.indexOf("行政区划(必填)");
        int xzqhcodeIndex = changecolumName.indexOf("行政区划代码(必填)");
        int jdIndex = changecolumName.indexOf("经度(必填)");
        int wdIndex = changecolumName.indexOf("纬度(必填)");
        if (first.size() != changecolumName.size() || !first.containsAll(changecolumName)
                || !changecolumName.containsAll(first)) {
            throw new ForestBaseException("您导入的Excel非标准模板，请下载标准模板导入");
        }

        for (int i = 1; i < data.size(); i++) {

            String id = "'" + UUID.randomUUID().toString().substring(0, 10) + "'";
            //拿到每一行的数据
            List<String> valueList = data.get(i);
            List<String> valueList1 = new ArrayList<>();
            for (int j = 0; j < valueList.size(); j++) {
                //判断当前的数据下标索引是否满足必填项目
                String d = valueList.get(j);
                checkMust(mcIndex, xzqhIndex, xzqhcodeIndex, jdIndex, wdIndex, j, d);

                if (StringUtils.isNotBlank(d)) {
                    d = "'" + d + "'";
                } else {
                    d = "'" + "" + "'";
                }
                valueList1.add(d);
            }
            String values = valueList1.toString().replace("[", "");
            String value = values.replace("]", "");
            //updateTableData(null,columnCodes,tableName,null,null);
            platMetaFieldMapper.commLeadDataInsert(id, tableName, colums, value, "'0'", "'1'", ("'" + realName + "'"),
                    ("'" + new Date() + "'"), "'1'", ("'" + realName + "'"), ("'" + new Date() + "'"), "'1'");
        }
    }


    @Override
    public void updateResourceShow(UpdateResourceShowDTO updateResourceShow) {
           platMetaTableMapper.updateResourceShow(updateResourceShow);
    }

    //修改资源分类等
    @Override
    @Transactional
    public void updateResourceCategory(UpdateResourceCategoryDTO updateResourceCategoryDTO) {
        //根据tableId更新plat_meta_table表中的信息
        platMetaTableMapper.updateCategory(updateResourceCategoryDTO);
        //更新fire_resource_category表中的对应信息
        fireResourceCategoryDao.updateCategory(Long.parseLong(updateResourceCategoryDTO.getCategory()),updateResourceCategoryDTO.getCategoryName(),
                                               updateResourceCategoryDTO.getImgUrl(),updateResourceCategoryDTO.getIconImg(),
                                              updateResourceCategoryDTO.getResourceName());

    }

    @Override
    public void addResourceCategory(AddResourceCategoryDTO addResourceCategoryDTO) {
        FireResourceCategory fireResourceCategory = new FireResourceCategory();
        fireResourceCategory.setCatName(addResourceCategoryDTO.getCategoryName());
        fireResourceCategory.setParentId(Long.getLong("0"));
        fireResourceService.addResource(fireResourceCategory);
    }

    private void checkMust(int mcIndex, int xzqhIndex, int xzqhcodeIndex, int jdIndex, int wdIndex, int j, String d) {
        if (j == mcIndex && StringUtils.isBlank(d)) {
            throw new ForestBaseException("Excel必填字段不能为空");
        }
        if (j == xzqhIndex && StringUtils.isBlank(d)) {
            throw new ForestBaseException("Excel必填字段不能为空");
        }
        if (j == xzqhcodeIndex && StringUtils.isBlank(d)) {
            throw new ForestBaseException("Excel必填字段不能为空");
        }
        if (j == jdIndex && StringUtils.isBlank(d)) {
            throw new ForestBaseException("Excel必填字段不能为空");
        }
        if (j == wdIndex && StringUtils.isBlank(d)) {
            throw new ForestBaseException("Excel必填字段不能为空");
        }
    }


    private void checkColums(List<String> first) {
        if (!first.contains("名称(必填)") || !first.contains("行政区划(必填)") || !first.contains("行政区划代码(必填)")
                || !first.contains("经度(必填)") || !first.contains("纬度(必填)")) {
            throw new ForestBaseException("您导入的Excel非标准模板，请下载标准模板导入");
        }
    }


    private List<String> changecolumName(Collection<String> columnNames) {
        List<String> columnName = new ArrayList<>();
        for (String name : columnNames) {
            if (name.equals("名称")) {
                name = name + "(必填)";
            }
            if (name.equals("行政区划")) {
                name = name + "(必填)";
            }
            if (name.equals("行政区划代码")) {
                name = name + "(必填)";
            }
            if (name.equals("经度")) {
                name = name + "(必填)";
            }
            if (name.equals("纬度")) {
                name = name + "(必填)";
            }
            columnName.add(name);
        }
        return columnName;
    }

    public static void main(String[] args) {
        List<Integer> a = Arrays.asList(1, 2, 3, 4);
        List<Integer> b = Arrays.asList(4, 3, 2, 1);
        System.out.println(compare(a, b));
    }

    public static <T extends Comparable<T>> boolean compare(List<T> a, List<T> b) {
        if (a.size() != b.size()) {
            return false;
        }
        Collections.sort(a);
        Collections.sort(b);
        for (int i = 0; i < a.size(); i++) {
            if (!a.get(i).equals(b.get(i))) {
                return false;
            }
        }
        return true;
    }

}
